package com.gopay.bis.manager.bank.ebank;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;


import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.nbcb.ebank.NbcbB2cMessage;
import com.gopay.common.domain.bank.nbcb.ebank.query.req.NbcbB2cQueryParam;
import com.gopay.common.domain.bank.nbcb.ebank.query.req.NbcbB2cReqList;
import com.gopay.common.domain.bank.nbcb.ebank.query.req.NbcbB2cReqNetPay;
import com.gopay.common.domain.bank.nbcb.ebank.query.res.NbcbB2cResNetPay;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;
import com.thoughtworks.xstream.XStream;

public class NbcbB2cManager implements BankManagerRemoteService {
	
	@Resource(name = "nbcbB2cBankServiceClientHna")
    private BankService nbcbB2cBankServiceClientHna;

	@Resource(name = "nbcbB2cBankServiceClient")
    private BankService nbcbB2cBankServiceClient;
	
    @Resource(name = "nbcbConfig")
    private Map<String, String> nbcbConfig;
    
    /** 分隔符 */
	private static final String separator = "|";
	
	/** 报文头 */
	private final static String XML_HEADER = "<?xml  version=\"1.0\" encoding=\"gb2312\" ?>\n";
	@Override
	public Object sign(BaseMessage msg) throws GopayException {
		NbcbB2cMessage message = (NbcbB2cMessage)msg;		
		message = buildB2C(message);
		message.setPlainMessage(getB2CPayPlainStr(message));
		BankLogUtils.printB2CManagerSignSendLog(message);
		String signMsg;
		if(message.isHna()){
			signMsg = (String) nbcbB2cBankServiceClientHna.sign(message);
		}else{
			signMsg = (String) nbcbB2cBankServiceClient.sign(message);
		}
		message.setMerSignMsg(signMsg);
		BankLogUtils.printB2CManagerSignReturnLog(message);
		return message;
	}

	@Override
	public Object verify(BaseMessage msg) throws GopayException {
		BankLogUtils.printB2CManagerVerifySendLog(msg);
		boolean flag;
		if(msg.isHna()){
			flag = (Boolean) nbcbB2cBankServiceClientHna.verify(msg);
		}else{
			flag = (Boolean) nbcbB2cBankServiceClient.verify(msg);
		}
		BankLogUtils.printB2CManagerVerifyReturnLog(msg, flag);
		return flag;
	}

	@Override
	public Object query(Object obj) throws GopayException {
		NbcbB2cReqNetPay message = (NbcbB2cReqNetPay)obj;
		message.setMerID(message.getMerID());
		message.setInitTranType(nbcbConfig.get("NBCB.TRANTYPE"));
		if(BisPayCheckUtils.checkExternalOrderID(message.getOrderId())){
			NbcbB2cReqList reqlist = new NbcbB2cReqList();
			reqlist.setInitOrderID(message.getOrderId());
			if(message.getOrderDate()!=null && !message.getOrderDate().equals("")){
				String orderDate = message.getOrderDate();
				reqlist.setInitOrderDate(orderDate.substring(0,8));
			}
			List list = new ArrayList<NbcbB2cReqList>();
			list.add(reqlist);
			message.setReq(list);
		}
		NbcbB2cQueryParam querParam = new NbcbB2cQueryParam();
		querParam.setReqMsg(buildB2CQueryMessage(message));
		querParam.setChannelName((String)nbcbConfig.get("NBCB.B2C.CHANNELNAME"));
		querParam.setVersion((String)nbcbConfig.get("NBCB.VERSION"));
		querParam.setOutStlmCd(BankConstants.BANK_LOGO_NBCB);
		querParam.setQueryUrl(message.getQueryUrl());
		BankLogUtils.printB2CManagerQuerySendLog(message, "");
		NbcbB2cResNetPay messageRepB2C;
		if(message.isHna()){
			messageRepB2C = (NbcbB2cResNetPay) nbcbB2cBankServiceClientHna.query(querParam);
		}else{
			messageRepB2C = (NbcbB2cResNetPay) nbcbB2cBankServiceClient.query(querParam);
		}
		messageRepB2C.setOutStlmCd(BankConstants.BANK_LOGO_NBCB);
		BankLogUtils.printB2CManagerQueryReturnLog(messageRepB2C);
		return messageRepB2C;
	}
	/**
	 * 设置银行B2C属性常量
	 * @param NbcbB2cMessage
	 * @return INbcbB2cMessage
	 */
	public NbcbB2cMessage buildB2C(NbcbB2cMessage message) {
		message.setMerId(message.getMerID());
		message.setBankUrl(message.getPayUrl());
		message.setChannelName((String)nbcbConfig.get("NBCB.B2C.CHANNELNAME"));
		message.setSecurityLevel((String)nbcbConfig.get("NBCB.SECURETYLEVEL"));
		message.setTranType((String)nbcbConfig.get("NBCB.TRANTYPE"));
		message.setVersion((String) nbcbConfig.get("NBCB.VERSION"));
		message.setCurrencyType((String) nbcbConfig.get("NBCB.CURRTYPE"));
		message.setSelfURI(message.getPayRuturnUrl());
		message.setPageURI(message.getPayNotifyUrl());
		message.setOrderDate(this.getCurrDate().substring(0,8));
		message.setOrderTime(this.getCurrDate().substring(8));
		message.setOrderAmount(TransUtils.amountConvert2Fen(message.getAmount().toString()));
		if (message.isSupportCredit()) {
			  message.setExtralData("1");
	    }
		return message;
	}

	/** 
	 * 构建B2C支付明文
	 * 
	 * @param NbcbB2cMessage
	 * @return String
	 */
	public String getB2CPayPlainStr(NbcbB2cMessage message) {
		StringBuffer sb = new StringBuffer();
		sb.append(message.getSecurityLevel()).append(separator)
		.append(message.getTranType()).append(separator)
		.append(message.getMerId()).append(separator)
		.append(message.getOrderDate()).append(separator)
		.append(message.getOrderTime()).append(separator)
		.append(message.getOrderId()).append(separator)
		.append(message.getCurrencyType()).append(separator)
		.append(message.getOrderAmount()).append(separator)
		.append(message.getOrderMono1()).append(separator)
		.append(message.getOrderMono2()).append(separator)
		.append(message.getPageURI()).append(separator)
		.append(message.getSelfURI()).append(separator)
		.append(message.getChannelName()).append(separator)
		.append(message.getVersion()).append(separator)
		.append(message.getExtralData());
		return sb.toString();
	}
	
	/**
	 * 构建B2C查询报文
	 * @param message
	 * @return
	 */
	private String buildB2CQueryMessage(NbcbB2cReqNetPay message) {
		StringBuffer sb = new StringBuffer();
		sb.append(XML_HEADER);
		XStream xstream = new XStream();
		xstream.autodetectAnnotations(true);
		xstream.processAnnotations(NbcbB2cReqNetPay.class);
		String body = xstream.toXML(message);
		sb.append(body);
		return sb.toString();
	}
	
	/**
	 * 获取当前时间
	 * @return String
	 */
	private String getCurrDate(){
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String s = sdf.format(date);
		return s;
		
	}

	@Override
	public Object dayend(BaseMessage base) throws GopayException, Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object refund(BaseMessage base) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

}
